package org.jeecgframework.web.service.impl;

import org.activiti.engine.TaskService;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.jeecgframework.core.common.exception.BusinessException;
import org.jeecgframework.core.constant.Globals;
import org.jeecgframework.core.util.ResourceUtil;
import org.jeecgframework.core.util.StringUtil;
import org.jeecgframework.core.util.oConvertUtils;
import org.jeecgframework.web.service.*;
import org.jeecgframework.web.system.pojo.base.*;
import org.jeecgframework.web.system.pojo.vo.ProcurementNote;
import org.jeecgframework.web.system.pojo.vo.ShoppingCar;
import org.jeecgframework.web.system.service.SystemService;
import org.jeecgframework.web.util.SendMailUtil;
import org.jeecgframework.web.util.StaticValue;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;


/**
 * Created by red on 2016/9/1.
 */
@Service("shoppingCarService")
public class CbsShoppingCarServiceImpl extends ZyCommonServiceImpl implements CbsShoppingCarServiceI {

    @Autowired
    private SystemService systemService;

    @Autowired
    private ZyWorkFlowService zyWorkFlowService;

    @Autowired
    private TaskService taskService;

    @Autowired
    private ZyPlanRecordServiceI zyPlanRecordService;

    @Autowired
    private CbsInvoiceInfoServiceI cbsInvoiceInfoService;
    
    @Autowired
	private CbsServiceServiceI cbsServiceServiceI;
    
    @Autowired
    private WxCommonService wxCommonService;

    @Autowired
    private CbsProcurementNoteServiceI cbsProcurementNoteService;

    public List<CbsShoppingCartEntity> getShoppingCarByUserName(String userName) {
        List<CbsShoppingCartEntity> results = systemService.findHql("from CbsShoppingCartEntity where createBy=? and noteEntity.id is null",userName);
        return results;
    }

    public void addProductToShoppingCar(CbsPartInfoEntity product, int num,String openId) {
        String userName = null == ResourceUtil.getSessionUserName() ? openId : ResourceUtil.getSessionUserName().getUserName();
        if(StringUtil.isNotEmpty(openId)){
            userName = openId;
        }
        if(oConvertUtils.isEmpty(userName)){
            return ;
        }
        String hql = "from CbsShoppingCartEntity cs where cs.part.id='%s' and cs.createBy='%s' and cs.noteEntity is null";
        List<CbsShoppingCartEntity> carItems = findByQueryString(String.format(hql,product.getId(),userName));
        if(carItems.size() > 0){
            carItems.get(0).setCount(carItems.get(0).getCount()+num);
            saveOrUpdate(carItems.get(0));
        }else{
            CbsShoppingCartEntity carItem = new CbsShoppingCartEntity();
            carItem.setCheckStatus(1);
            carItem.setPart(product);
            carItem.setCount(num);
            carItem.setCreateBy(openId);
            carItem.setCreateDate(new Date());
            save(carItem);
        }
    }


    public void reduceShoppingCar(CbsShoppingCartEntity product, int num,String userName) {

        if(product != null){
            reduceShoppingCar(product.getId(),num,userName);
        }
    }

    public void reduceShoppingCar(String productId, int num, String userName) {

        String deleteSql = "delete from cbs_shopping_cart where part_id='%s' and create_by='%s' and order_id is null";

        if(num == 0){
            systemService.executeSql(String.format(deleteSql,productId,userName));
        }else if(num > 0){
//            systemService.executeSql(String.format(updateSql,num,productId,userName));
            addProductToShoppingCar(productId,-1*num);
        }

    }


    public void emptyShoppingCar(String userName) {
        String emptySql = "delete from cbs_shopping_cart where create_by='%s' and order_id is null";
        systemService.executeSql(String.format(emptySql,userName));
    }

    public ShoppingCar generateShoppingCarWithOpenId(String openId){
        ShoppingCar sc = new ShoppingCar();
        if(StringUtil.isNotEmpty(openId)){
            generateCar(openId,sc);
        }
        return sc;
    }

    public ShoppingCar generateShoppingCar(String userName) {
        ShoppingCar sc = new ShoppingCar();
        List<TSBaseUser> users = systemService.findHql("from TSBaseUser where userName='"+userName+"'");
        if(users != null && users.size() > 0){
            sc.setPermission(oConvertUtils.getInt(users.get(0).getAuthenticationLevel()));
            sc.setUserName(userName);
            sc.setRealName(users.get(0).getRealName());
            generateCar(userName,sc);
        }
        return sc;
    }

    public ShoppingCar generateCar(String createBy,ShoppingCar sc){
        if(null == sc){
            sc = new ShoppingCar();
        }
        for(CbsShoppingCartEntity carItem : getShoppingCarByUserName(createBy)){
            double total =  carItem.getCount() * carItem.getPart().getWechatPrice();
            sc.setTotalCount(sc.getTotalCount() + carItem.getCount());
            sc.setTotalPrice(sc.getTotalPrice() + total);
            sc.getDetails().add(carItem);
            if(carItem.getCheckStatus() == 1){
                sc.setCheckedCount(sc.getCheckedCount()+carItem.getCount());
                sc.setCheckedPrice(sc.getCheckedPrice() + total);
            }
            //sc.getTotalPrice() + carItem.getCount() * carItem.getPart().getWechatPrice()
        }
        BigDecimal bd = new BigDecimal(sc.getCheckedPrice());
        sc.setCheckedPrice(bd.setScale(2,BigDecimal.ROUND_HALF_DOWN).doubleValue());
        return sc;
    }

    public void addProductToShoppingCar(String productId, int num) {
        CbsPartInfoEntity pro = systemService.get(CbsPartInfoEntity.class,productId);
        if(pro != null){
            addProductToShoppingCar(pro,num,"");
        }
    }

    public void addProductToShoppingCar(String productId,int num,String openId){
        if(StringUtil.isEmpty(openId)){
            return;
        }else{
            CbsPartInfoEntity pro = systemService.get(CbsPartInfoEntity.class,productId);
            if(null == pro){
                return;
            }else{
                addProductToShoppingCar(pro,num,openId);
            }
        }
    }

    public void updateProductNum(String productId,int num,String userName){
        String updateSql = "update cbs_shopping_cart set count=%s where part_id='%s' and create_by='%s' and order_id is null";
        if(num > 0){
            systemService.executeSql(String.format(updateSql,num,productId,userName));
        }
    }


    public ProcurementNote orderFromCar(ProcurementNote note,String openId) {
        note.setSuccess(true);
        TSUser user = ResourceUtil.getSessionUserName();
        final CbsProcurementNoteEntity procurement = new CbsProcurementNoteEntity();
        if(null == user || !user.ifGoldMedal()){
            procurement.setCreateBy(openId);
            procurement.setCreateDate(new Date());
        }
        if(user != null && user.ifGoldMedal()){
            procurement.setSource("2");
        }else{
            procurement.setSource("3");
            procurement.setSnNo(note.getSelectedEquip());
            procurement.setCinemaName(note.getCinemaName());
        }
        procurement.setState("0");
        procurement.setClientType("0");
        if(StringUtil.isEmpty(procurement.getWarranty())){
            procurement.setWarranty(oConvertUtils.getString(systemService.getTypeByCode("commonDesc","desc_bxq")));
        }
        procurement.setProcurementNo(cbsProcurementNoteService.genProcurementNo());
        // TODO: 2016/9/23 clientType未设置

        procurement.setContactMail(note.getContactEmail());
        procurement.setContactName(note.getContactName());
        procurement.setContactPhone(note.getContactPhone());
        procurement.setFullAddress(note.getFullAddress());
        procurement.setIsOnsiteServices(note.getIsOnsiteServices());

        if(!"".equals(note.getCinemaId())){
            procurement.setCinema(get(ZyCinemaEntity.class,oConvertUtils.getString(note.getCinemaId())));
        }

        save(procurement);
        note.setNoteId(procurement.getProcurementNo());
        if(StringUtil.isNotEmpty(note.getInvoiceId())){
            CbsInvoiceSnapEntity invoice = note.assebleNoteInvoice(get(CbsInvoiceInfoEntity.class,note.getInvoiceId()));
            if(invoice != null){
                if(StringUtil.isNotEmpty(note.getCinemaId())){
                    invoice.setBelongCinema(super.get(ZyCinemaEntity.class,note.getCinemaId()));
                }

                super.save(invoice);

                procurement.setInvoice(invoice);
            }
        }


        updateEntitie(procurement);
        if(user != null && user.ifGoldMedal()){
            handlePartEs(note,procurement);
            handlePart(note,procurement,"");
        }else{
            handlePart(note,procurement,openId);
        }



        updateEntitie(procurement);

        //钻石用户进入采购订单流程
        if(user != null && user.ifGoldMedal()){
            ProcessInstance inst = zyWorkFlowService.startOnlineProcess("cbs_procurement_note", procurement.getId(), new HashMap<String, Object>());
            zyWorkFlowService.goProcessNode(procurement.getId(), StaticValue.CBS_PART_FLOW_KEY, "taskNode0", "taskNode1");
            Task task = taskService.createTaskQuery().processInstanceId(inst.getProcessInstanceId()).active().singleResult();
            zyPlanRecordService.savePlanRecord(procurement.getId(), inst.getProcessInstanceId(), task.getId(), "", user.getUserName(), "发起");
        }
        //所有都创建服务单
    	CbsServiceEntity service=new CbsServiceEntity();

		String sn=procurement.getSnNo();
		CbsServiceTypeEntity sType1=systemService.singleResult("from CbsServiceTypeEntity where type=0 and name='咨询'");
		CbsServiceTypeEntity sType2=systemService.singleResult("from CbsServiceTypeEntity where type=1 and name='购买零件'");
		try{
	        if(procurement.getCinema() != null){
	        	service.setZyCinemaName(procurement.getCinema().getName());
	        } else {
	        	service.setZyCinemaName(procurement.getCinemaName());
	        }
			service.setContactsName(procurement.getContactName());
			service.setContactsPhone(procurement.getContactPhone());
			service.setEmail(procurement.getContactMail());
			service.setAddress(procurement.getFullAddress());
			String strdes = "";
			double total = 0;
			// 零件信息
			for (CbsProcurementPartEntity PartEntity : procurement.getPartList()) {
				strdes+="零件名称:"+PartEntity.getPartInfo().getWechatName()+";数量:"+PartEntity.getNum()+";单价:"+PartEntity.getPrice()+"\r\n";
				total += Integer.parseInt(PartEntity.getNum())*PartEntity.getPrice();
			}
			procurement.setTotalPrice(total);
			strdes+="总价:"+total+"\r\n";
			
			//是否上门
			if (procurement.getIsOnsiteServices().equals("1")){
				strdes+="是否上门：是"+"\r\n";
			} else{
				strdes+="是否上门：否"+"\r\n";
			}
			//发票信息
	        if(procurement.getInvoice() != null){
	            CbsInvoiceSnapEntity invoice = procurement.getInvoice();
	            strdes+="发票抬头："+invoice.getInvoiceTitle()+"\r\n";
	            strdes+="税号："+invoice.getClientTaxnum()+"\r\n";
	            strdes+="银行名称："+invoice.getClientBankname()+"\r\n";
	            strdes+="银行账号："+invoice.getClientBankaccount();
	        }
	        
			service.setDescription(strdes);
			service.setServiceType1(sType1);
			service.setServiceType2(sType2);
			service.setSourceType("2");
			service.setStatus("1");
			if (procurement.getPaertEsList() != null) {
				String strtep = procurement.getPaertEsList().get(0).getEquipmentSpare().getSn();
				for (int i =1;i<procurement.getPaertEsList().size();i++) {
					strtep +=";"+procurement.getPaertEsList().get(i).getEquipmentSpare().getSn();
				}
				service.setSn(strtep);
			} else {
				service.setSn(sn);
			}
			service.setSpeedStatus("0");

			ZyEquipmentSpareEntity zyEquipmentSpare=systemService.singleResult("from ZyEquipmentSpareEntity where sn='"+sn+"'");
			if(zyEquipmentSpare!=null){
				service.setZyEquipmentSpareId(zyEquipmentSpare);
			}
			ZyCinemaEntity cinema=systemService.singleResult("from ZyCinemaEntity where name='"+procurement.getCinemaName()+"'");
			if(cinema!=null){
				service.setZyCinemaId(cinema);
				service.setProvince(cinema.getProvince());
				if(cinema.getCity()!=null){
					TSTerritory city=systemService.get(TSTerritory.class,cinema.getCity());
					service.setCity(city);
				}
			}
			service.setAddress(procurement.getFullAddress());

			String hql="from ZyContactsEntity where cellphone1='"+procurement.getContactPhone()+"' or cellphone2='"+procurement.getContactPhone()+"'";
			List<ZyContactsEntity> zyContacts=systemService.findHql(hql);
			if(zyContacts.size()>0){
				service.setZyContactsId(zyContacts.get(0));
			}

			//新的服务单号
			Map noMap=cbsServiceServiceI.getNo();
			String code=(String) noMap.get("no");

			service.setCode(code);
			String createBy="";
			String createName="";
			if(user!=null && StringUtil.isNotEmpty(user.getUserName())){
				createBy=user.getUserName();
			}else{
				createBy=openId;
			}
			if(user!=null && StringUtil.isNotEmpty(user.getRealName())){
				createName=user.getRealName();
			}else{
				createName=procurement.getContactName();
			}
			
			service.setCreateBy(createBy);
			service.setCreateName(createName);
			service.setCreateDate(new Date());
			systemService.save(service);

			//添加日志
			wxCommonService.addServiceLog(service.getId());

			//调用微信接口发送
			List<Map<String,String>> list=new ArrayList<>();
			String serviceCode="";
			if(service!=null){
				serviceCode=service.getCode();
			}
			String content="";
			if (procurement.getIsOnsiteServices().equals("1")){
				content="尊敬的客户：您的放映机<"+service.getSn()+">的采购订单已提交，服务单号：<"+serviceCode+">。正式报价单将在一个工作日内发送至您的邮箱。【中影巴可客服部】";
			} else {
				content="尊敬的客户：您的放映机<"+service.getSn()+">的采购订单已提交，服务单号：<"+serviceCode+">。订单确认邮件已发送至您的邮箱，请您查阅。"+"\r\n"
						+ "急单可参照确认邮件指示先行付款。正式报价单将在一个工作日内发送至您的邮箱。【中影巴可客服部】";
			}
			
			if(StringUtil.isNotEmpty(openId)){
				Map<String,String> map=new HashMap<>();
				map.put("openid",openId);
				map.put("message",content);
				list.add(map);
				wxCommonService.sendMsgForWx(list);
			}
			//发送邮件给HD
			wxCommonService.sendMail(service);
			
			if (!procurement.getIsOnsiteServices().equals("1")){
				// 发邮件给客户
	            String subject = "中影巴可易服务采购订单确认-"+serviceCode;
	            String logo  = StaticValue.HTTP_HEADER+"/plug-in/login/images/logo.png";
	            Map<String,Object> param = new HashMap<String, Object>();
	            param.put("logoCid",logo);
	            param.put("serviceCode",serviceCode);
	            param.put("total",total);
	            param.put("partList",procurement.getPartList());
	            param.put("receiver","candice.wang@cfg-barco.com");
	            SendMailUtil.sendMailWithAttachForWXorder(procurement.getContactMail(),subject,null,null,"mail_wx_quotation_send_mail.ftl",param,systemService);
			}
			systemService.addLog("提交备件采购", Globals.Log_Type_INSERT, Globals.Log_Leavel_INFO);
			
			note.setNoteId(serviceCode);
			}catch(Exception e){
				e.printStackTrace();
				systemService.addLog("添加失败", Globals.Log_Type_INSERT, Globals.Log_Leavel_INFO);
				throw new BusinessException(e.getMessage());
			}
		
//            Map param = new HashMap();
//            param.put("serviceType","零件采购");
//            param.put("page",procurement);
//            List<TSType> mailType = findHql("from TSType where TSTypegroup.typegroupcode=?", StaticValue.DIC_SERVICE_MAILADDRESS);
//            for (TSType tsType : mailType) {
//                if(StringUtil.isNotEmpty(tsType.getTypename())){
//                    String subject = StaticValue.DIC_SERVICE_MAIL_PREFIX+"-零件采购-"+procurement.getProcurementNo()+"-"+procurement.getCinemaName();
//                    SendMailUtil.sendHTMLeMail(tsType.getTypename(),subject,"mail_wx_order_service.ftl",param,systemService);
//                }
//            }
        
        return note;
    }

    public CbsInvoiceInfoEntity handleInvoice(ProcurementNote note){
        if(oConvertUtils.isNotEmpty(note.getInvoiceId())){
            CbsInvoiceInfoEntity invoice = get(CbsInvoiceInfoEntity.class,note.getInvoiceId());
            return cbsInvoiceInfoService.snapInvoiceInfo(invoice);
        }
        return new CbsInvoiceInfoEntity();
    }



    public List<CbsProcurementPartEntity> handlePart(ProcurementNote note,CbsProcurementNoteEntity procurement,String openId){
        String createBy = openId;
        if(StringUtil.isEmpty(createBy)){
            TSUser user = ResourceUtil.getSessionUserName();
            createBy = user.getUserName();
        }
        String sel = oConvertUtils.getString(note.getSelectedPro()).replace(",","','");
        List<CbsShoppingCartEntity> carItem = findHql("from CbsShoppingCartEntity where id in ('"+sel+"') and createBy='"+createBy+"' and checkStatus=1 and noteEntity.id is null");
        List<CbsProcurementPartEntity> proParts = new ArrayList<CbsProcurementPartEntity>();
        if(carItem.size() == note.getSelectedPro().split(",").length){

            for(CbsShoppingCartEntity item : carItem){
                item.setNoteEntity(procurement);
                updateEntitie(item);
                CbsProcurementPartEntity proPart = new CbsProcurementPartEntity();
                proPart.setPartInfo(item.getPart());
                proPart.setProcurement(procurement);
                proPart.setNum(oConvertUtils.getString(item.getCount()));
                cbsProcurementNoteService.setNotePartPrice(proPart);
                proParts.add(proPart);
            }
            batchSave(proParts);
            procurement.setPartList(proParts);
        }
        return proParts;
    }

    public List<CbsProcurementPartEsEntity> handlePartEs(ProcurementNote note,CbsProcurementNoteEntity procurement){
        String sel = oConvertUtils.getString(note.getSelectedEquip()).replace(",","','");
        List<CbsProcurementPartEsEntity> partEs = new ArrayList<CbsProcurementPartEsEntity>();
        List<ZyEquipmentSpareEntity> equips = findHql("from ZyEquipmentSpareEntity where id in('"+sel+"')");
        if(equips.size() > 0){
            for(ZyEquipmentSpareEntity equip : equips){
                CbsProcurementPartEsEntity proEq = new CbsProcurementPartEsEntity();
                proEq.setProcurementNoteId(procurement.getId());
                proEq.setEquipmentSpare(equip);
                partEs.add(proEq);
            }
            batchSave(partEs);
            procurement.setPaertEsList(partEs);
        }
        return partEs;
    }

}
